function BrowserType() {
  // 权重：系统 + 系统版本 > 平台 > 内核 + 载体 + 内核版本 + 载体版本 > 外壳 + 外壳版本
  const ua = navigator.userAgent.toLowerCase();
  //'mozilla/5.0 (windows nt 6.1; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/97.0.4692.71 safari/537.36'
  const testUa = (regexp) => regexp.test(ua);
  const testVs = (regexp) =>
    (ua.match(regexp) + '').replace(/[^0-9|_.]/gi, '').replace(/_/gi, '.');

  // 系统
  let system = (() => {
    if (testUa(/windows|win32|win64|wow32|wow64/gi)) {
      return 'windows';
    } // window系统
    if (testUa(/macintosh|macintel/gi)) {
      return 'osx';
    } // osx系统
    if (testUa(/x11/gi)) {
      return 'linux';
    } // linux系统
    if (testUa(/android|adr/gi)) {
      return 'android';
    } // android系统
    if (testUa(/ios|iphone|ipad|ipod|iwatch/gi)) {
      return 'ios';
    } // ios系统
    if (testUa(/openharmony/gi)) {
      return '鸿蒙';
    }
    return '未知系统';
  })();

  // 系统版本
  let systemVs = ((system) => {
    if (system === 'windows') {
      if (testUa(/windows nt 5.0|windows 2000/gi)) {
        return '2000';
      }
      if (testUa(/windows nt 5.1|windows xp/gi)) {
        return 'xp';
      }
      if (testUa(/windows nt 5.2|windows 2003/gi)) {
        return '2003';
      }
      if (testUa(/windows nt 6.0|windows vista/gi)) {
        return 'vista';
      }
      if (testUa(/windows nt 6.1|windows 7/gi)) {
        return '7';
      }
      if (testUa(/windows nt 6.2|windows 8/gi)) {
        return '8';
      }
      if (testUa(/windows nt 6.3|windows 8.1/gi)) {
        return '8.1';
      }
      if (testUa(/windows nt 10.0|windows 10/gi)) {
        return '10';
      }
      if (testUa(/openharmony 5.0/gi)) {
        return '鸿蒙 5.0';
      }
    }
    if (system === 'osx') {
      return testVs(/os x [\d._]+/gi);
    }
    if (system === 'android') {
      return testVs(/android [\d._]+/gi);
    }
    if (system === 'ios') {
      return testVs(/os [\d._]+/gi);
    }
    return '未知系统版本';
  })(system);
  // 平台
  let platform = (() => {
    if (system === 'windows' || system === 'osx' || system === 'linux') {
      return 'desktop';
    } // 桌面端
    if (system === 'android' || system === 'ios' || testUa(/mobile/gi)) {
      return 'mobile';
    } // 移动端
    return '未知平台';
  })();

  // 内核
  let engine = (() => {
    if (testUa(/applewebkit/gi)) {
      return 'webkit';
    } // webkit内核
    if (testUa(/safari/gi)) {
      return 'webkit';
    } // webkit内核

    if (testUa(/gecko/gi)) {
      return 'gecko';
    } // gecko内核
    if (testUa(/firefox/gi)) {
      return 'gecko';
    } // gecko内核

    if (testUa(/presto/gi)) {
      return 'presto';
    } // presto内核
    if (testUa(/trident|compatible|msie/gi)) {
      return 'trident';
    } // trident内核
    return '未知内核';
  })();
  // 内核版本
  let engineVs = ((engine) => {
    if (engine === 'webkit') {
      return testVs(/applewebkit\/[\d.]+/gi);
    }
    if (engine === 'gecko') {
      return testVs(/gecko\/[\d.]+/gi);
    }
    if (engine === 'presto') {
      return testVs(/presto\/[\d.]+/gi);
    }
    if (engine === 'trident') {
      return testVs(/trident\/[\d.]+/gi);
    }
    return '未知内核版本';
  })(engine);
  // 载体
  let supporter = ((engine) => {
    if (engine === 'webkit') {
      if (testUa(/edge/gi)) {
        return 'edge';
      } // edge浏览器
      if (testUa(/opr/gi)) {
        return 'opera';
      } // opera浏览器
      if (testUa(/chrome/gi)) {
        return 'chrome';
      } // chrome浏览器
      return 'safari'; // safari浏览器
    }
    if (engine === 'gecko') {
      return 'firefox';
    } // firefox浏览器
    if (engine === 'presto') {
      return 'opera';
    } // opera浏览器
    if (engine === 'trident') {
      return 'iexplore';
    } // iexplore浏览器
    return '未知载体';
  })(engine);
  // 载体版本
  let supporterVs = ((supporter) => {
    if (supporter === 'chrome') {
      return testVs(/chrome\/[\d.]+/gi);
    }
    if (supporter === 'safari') {
      return testVs(/version\/[\d.]+/gi);
    }
    if (supporter === 'firefox') {
      return testVs(/firefox\/[\d.]+/gi);
    }
    if (supporter === 'opera') {
      return testVs(/opr\/[\d.]+/gi);
    }
    if (supporter === 'iexplore') {
      return testVs(/(msie [\d.]+)|(rv:[\d.]+)/gi);
    }
    if (supporter === 'edge') {
      return testVs(/edge\/[\d.]+/gi);
    }
    return '未知载体版本';
  })(supporter);

  // 实际应用：判断浏览器函数
  let isMobile = (() => {
    return testUa(
      /(phone|pad|pod|iphone|ipod|ios|ipad|android|mobile|blackberry|iemobile|mqqbrowser|juc|fennec|wosbrowser|browserng|webos|symbian|windows phone)/gi
    );
  })();
  let isWechart = (() => {
    if (isMobile) {
      if (testUa(/micromessenger/gi)) {
        return true;
      }
    }
    return false;
  })();

  // 外壳和外壳版本
  let [shell, shellVs] = (() => {
    if (isWechart) {
      return ['微信浏览器', testVs(/micromessenger\/[\d.]+/gi)];
    }
    if (testUa(/qqbrowser/gi)) {
      return ['QQ浏览器', testVs(/qqbrowser\/[\d.]+/gi)];
    }
    if (testUa(/ubrowser/gi)) {
      return ['UC浏览器', testVs(/ubrowser\/[\d.]+/gi)];
    }
    if (testUa(/2345explorer/gi)) {
      return ['2345浏览器', testVs(/2345explorer\/[\d.]+/gi)];
    }
    if (testUa(/metasr/gi)) {
      return ['搜狗浏览器', '未知搜狗版本'];
    }
    if (testUa(/lbbrowser/gi)) {
      return ['猎豹浏览器', '未知猎豹版本'];
    }
    if (testUa(/maxthon/gi)) {
      return ['遨游浏览器', testVs(/maxthon\/[\d.]+/gi)];
    }
    if (testUa(/bidubrowser/gi)) {
      return ['百度浏览器', testVs(/bidubrowser [\d.]+/gi)];
    }
    return ['未知外壳', '未知外壳版本'];
  })();

  return Object.assign(
    {},
    {
      系统: system, // windows osx linux android ios
      系统版本: systemVs,
      内核: engine, // webkit gecko presto trident
      内核版本: engineVs,
      平台: platform, // desktop mobile
      载体: supporter, // chrome safari firefox opera iexplore edge
      载体版本: supporterVs,
      是移动端: isMobile,
      是微信: isWechart,
      外壳: shell, // wechat qq uc 2345 sougou liebao maxthon baidu
      外壳版本: shellVs,
    }
  );
}

function compareVersion(v1, v2) {
  //版本对比
  v1 = v1.split('.');
  v2 = v2.split('.');
  const len = Math.max(v1.length, v2.length);
  while (v1.length < len) {
    v1.push('0');
  }
  while (v2.length < len) {
    v2.push('0');
  }
  let res = (() => {
    for (let i = 0; i < len; i++) {
      const num1 = parseInt(v1[i]) || 0;
      const num2 = parseInt(v2[i]) || 0;
      if (num1 > num2) {
        return 1;
      }
      if (num1 < num2) {
        return -1;
      }
    }
    return 0;
  })();
  return {
    isNewer: res === 1,
    isOlder: res === -1,
    isSame: res === 0,
  };
}

export { BrowserType, compareVersion };
